#import "MRPickerView.h"
#import <objc/runtime.h>

#define BACK_COLOR      rgba(255,255,255, .85)
#define	ENDLESS			10000

@implementation UIPickerView (MRPickerView)

+ (void)load
{
	Method fun = class_getInstanceMethod(self, @selector(layoutSubviews));
	Method new = class_getInstanceMethod(self, @selector(fsLayoutSubviews));
	method_exchangeImplementations(fun, new);
}

- (void)fsLayoutSubviews
{
	[self fsLayoutSubviews];
	
	for (NSInteger i=1; i<self.subviews.count; i++)
	{
		self.subviews[i].backgroundColor = rgba(127, 127, 127, .3);
	}
}

@end

/*===================================================================
 说明:
    选择器组件
 ==================================================================*/
#pragma mark - 选择器组件
@implementation MRPickerComponent

+ (instancetype)componentWithPickerView:(MRPickerView *)pickerView
{
	MRPickerComponent *component = [[MRPickerComponent alloc] initWithPickerView:pickerView withLoop:YES];
	return component;
}

/*===================================================================
 说明:
	初始化
 ==================================================================*/
- (instancetype)initWithPickerView:(MRPickerView *)pickerView withLoop:(BOOL)loop
{
    if (self = [super init])
    {
		_pickerView = pickerView;
		self.backgroundColor = [UIColor clearColor];
		
		_picker = [UIPickerView new];
		_picker.delegate = self;
		_picker.dataSource = self;
		_picker.clipsToBounds = YES;
        _picker.backgroundColor = [UIColor clearColor];
		
		[_picker addConstraintEqualSuperview:self];
		
        _width  = -1;
		_isLoop = loop;
		
		//内容预设
        _content = [[MRLabel alloc] init];
		_content.adjustsFontSizeToFitWidth = YES;
		_content.minimumScaleFactor = .5;
		//_content.shadowColor = [UIColor whiteColor];
		//_content.shadowOffset = CGSizeMake(0, 1);
		//_content.backgroundColor = [UIColor clearColor];
		_content.numberOfLines = 0;
		_content.textAlignment = NSTextAlignmentCenter;
		_content.font = [UIFont systemFontOfSize:17];
		_content.contentInset = UIEdgeInsetsMake(3, 5, 3, 5);
		
		//单位
		_unit = [[MRLabel alloc] init];
		_unit.tag = MRSkinColorGrayText;
		//_unit.shadowColor = [UIColor whiteColor];
		//_unit.shadowOffset = CGSizeMake(0, 1);
		//_unit.backgroundColor = [UIColor clearColor];
		_unit.font = [UIFont systemFontOfSize:15];
		
		[self addSubview:_unit];
    }
	
    return self;
}

/*===================================================================
 说明:
	被选择执行块
 ==================================================================*/
- (void)didSelect:(ComponentHandler)handler
{
	_handler = handler;
}

/*===================================================================
 说明:
	重载组件
 ==================================================================*/
- (void)reloadComponent
{
	_copyContent = nil;
	
	[_picker reloadAllComponents];
	
	if (_isLoop && _maxValue > _minValue)	//无限模式下初始居中
	{
		NSInteger row = _decimal ? _maxValue - _minValue : _items.count;
		row = (ENDLESS / 2 / row) * row + _lastIndex;
		
		[_picker selectRow:row inComponent:0 animated:NO];
	}
	
	_lastRow = [_picker selectedRowInComponent:0];
}

/*===================================================================
 说明:
    组件索引
 ==================================================================*/
- (void)setIndex:(NSInteger)index animated:(BOOL)animated
{
	if (index == -1) index = _maxValue - _minValue - 1;
	
	if (_isLoop)
	{
		index = [_picker selectedRowInComponent:0] + (index - self.index);
	}
	
	_lastRow = index;
    [_picker selectRow:index inComponent:0 animated:animated];
	
	if (_handler) _handler(self);
}

- (void)setIndex:(NSInteger)index
{
    [self setIndex:index animated:YES];
}

- (NSInteger)index
{
	NSInteger index = [_picker selectedRowInComponent:0];
	
	//无限模式下转换为当前对应索引
	if (_isLoop && _maxValue > _minValue) index %= _maxValue - _minValue;
	
    return index;
}

/*===================================================================
 说明:
	当前值
==================================================================*/
- (NSInteger)value
{
	return (self.index + _minValue);
}

- (void)setValue:(NSInteger)value
{
	if (value < _minValue) value = _minValue;
	if (value > _maxValue) value = _maxValue;
	
	[self setIndex:value - _minValue animated:YES];
}

- (CGFloat)scaleValue
{
	return (self.value * _scale);
}

- (void)setScaleValue:(CGFloat)scaleValue
{
	[self setValue:lround(scaleValue / _scale)];
}

#pragma mark - 组件内容设置
/*===================================================================
 说明:
    设置显示内容项目数组
 ==================================================================*/
- (void)setItems:(NSArray *)items
{
    _items = items;
    _scale = 1;
    _minValue = _decimal = 0;
	_maxValue = items.count;
	
	_lastIndex = self.index;
    [self reloadComponent];
}

- (void)addItem:(NSString *)item
{
	_items = [_items arrayByAddingObject:item];
	_maxValue = _items.count;
	
	_lastIndex = self.index;
	[self reloadComponent];
}

/*===================================================================
 说明:
    设置范围格式、大小
 ==================================================================*/
- (MRPickerComponent *)setRangeWithMax:(NSInteger)max
{
	return [self setRangeWithFormat:@"%d" withMax:max withMin:0];
}

- (MRPickerComponent *)setRangeWithMax:(NSInteger)max withMin:(NSInteger)min
{
	return [self setRangeWithFormat:@"%d" withMax:max withMin:min];
}

- (MRPickerComponent *)setRangeWithFormat:(NSString *)format withMax:(NSInteger)max withMin:(NSInteger)min
{
	_lastIndex = self.index;
	
    _format   = format;
	_decimal  = 1;
    _minValue = min;
	_maxValue = max > min ? max + 1 : min;  //加1将显示最大值
    
    //显示小数点
    NSRange range = [format rangeOfString:@"."];
    if (range.length && range.location != 2)
    {
        range.location ++;
        uint len = [[format substringWithRange:range] intValue];
        
        for (uint i=0; i<len; i++) _decimal *= 10;
    }
    
    //放大率
    CGFloat zoom = 1;
    range = [format rangeOfString:@"*"];
    if (range.length)
    {
        _format = [format substringToIndex:range.location];
        zoom = [[format substringFromIndex:range.location + 1] floatValue];
    }
    
    _isFloat = (_decimal >= 10 || [_format rangeOfString:@"f"].length);
	_scale = zoom / _decimal;
    
    [self reloadComponent];
	
	return self;
}

#pragma mark - 选择器控制
/*===================================================================
 说明:
	选择器控制
 ==================================================================*/
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
	CGFloat y = (pickerView.bounds.size.height - self.pickerView.rowHeight) / 2;
	_unit.frame = CGRectMake(self.bounds.size.width*.7, y, self.bounds.size.width*.3, self.pickerView.rowHeight);
	
	return 1;
}

//可选数
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
	if (_maxValue < _minValue)
		return 0;
	else if (_maxValue - _minValue <= 1)
		return 1;
	else if (_isLoop)
		return ENDLESS;
	else
		return _maxValue - _minValue;
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
	return self.pickerView.rowHeight;
}

//内容
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
{
	if (_maxValue < _minValue) return nil;
	
	//从内容复制创建对象副本
	if (!_copyContent) _copyContent = [NSKeyedArchiver archivedDataWithRootObject:_content];
	MRLabel	*lab = [NSKeyedUnarchiver unarchiveObjectWithData:_copyContent];
	lab.contentInset = _content.contentInset;
	lab.frame = CGRectMake(0, 0, self.bounds.size.width, self.pickerView.rowHeight);
	
	//无限模式转换
	if (_isLoop && (_maxValue > _minValue)) row %= _maxValue - _minValue;
	
	//显示小数或整数
	if (_isFloat)
	{
		lab.text = [NSString stringWithFormat:_format, (row + _minValue) * _scale];
	}
	else if (_decimal == 1)
	{
		lab.text = [NSString stringWithFormat:_format, lround((row + _minValue) * _scale)];
	}
	else if (row < _items.count)
	{
		if ([_items[row] isKindOfClass:[NSDictionary class]])
			lab.text = _items[row][@"name"];		//如果是字典，则获取@"name"键的值
		else
			lab.text = _items[row];
	}

	return lab;
}

//选择内容
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
	if (row != _lastRow)
	{
		_lastRow = row;
		if (_handler) _handler(self);
	}
}

@end

//选择器==========================================================
#pragma mark - 选择器视图
@implementation MRPickerView

/*===================================================================
 说明:
    参数窗口
 ==================================================================*/
- (instancetype)initWithBar:(UIView *)bar
{
	if (self = [self init])
	{
		_barView = bar;
		
		CGRect frame = self.frame;
		frame.size.height += bar.bounds.size.height;
		self.frame = frame;
		
		[self addSubview:bar];
	}
	
	return self;
}

- (id)init
{
	return [self initWithFrame:CGRectZero];
}

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
		self.backgroundColor = [UIColor clearColor];
		[self awakeFromNib];
		
		CGSize size = [UIScreen mainScreen].bounds.size;
		if (frame.size.width == 0)  frame.size.width  = size.width;
		if (frame.size.height == 0) frame.size.height = DIS35 ? 180 : size.width * .64;
		self.frame = frame;
		
		_rowHeight = lrint(frame.size.height / (DIS35 ? 5 : 6.4));
    }
    return self;
}

- (void)awakeFromNib
{
	[super awakeFromNib];
	
	_components = [NSMutableArray array];
	
	//self.backgroundColor = rgba(0, 0, 0, .3);
	self.rowHeight = 180 / 5;
	self.userInteractionEnabled = YES;
	
	if (!self.superview)
	{
		[[UIToolbar new] addConstraintEqualSuperview:self];
	}
}

- (void)layoutSubviews
{
	[self layoutWithAnimated:NO];
	[super layoutSubviews];
	
	if ([_barView isKindOfClass:[UIToolbar class]])
	{
		for (UIView *view in _barView.subviews)
		{
			if ([view isKindOfClass:[UIImageView class]])
			{
				view.hidden = YES;
				break;
			}
		}
	}
}

/*===================================================================
 说明:
	重新布局
 ==================================================================*/
- (void)layoutWithAnimated:(BOOL)animated
{
	CGFloat width = 0;
	for (MRPickerComponent *component in _components)
	{
		width += component.width == -1 ? 1.f/_components.count : component.width;
	}
	
	CGFloat h = _barView.bounds.size.height;
	[UIView animateWithDuration:(animated ? .25 : 0) animations:^{
		CGFloat x = 0;
		for (MRPickerComponent *c in _components)
		{
			CGFloat w = self.bounds.size.width * (c.width == -1 ? 1.f/_components.count : c.width) / width;
			c.frame = CGRectMake(x, h, w, self.bounds.size.height - h);
			
			x += w;
		}
	}];
}

#pragma mark - 组件管理
/*===================================================================
 说明:
    添加组件
 ==================================================================*/
- (MRPickerComponent *)addComponent
{
    return [self addComponentWithLoop:NO withUnit:nil];
}

- (MRPickerComponent *)addComponentWithLoop:(BOOL)loop
{
	return [self addComponentWithLoop:loop withUnit:nil];
}

- (MRPickerComponent *)addComponentWithLoop:(BOOL)loop withUnit:(NSString *)unit
{
	MRPickerComponent *component = [[MRPickerComponent alloc] initWithPickerView:self withLoop:loop];
	component.unit.text = unit;
	
    [_components addObject:component];
	[self addSubview:component];
	[self setNeedsLayout];
	
    return component;
}

- (MRPickerComponent *)insertComponentWithLoop:(BOOL)loop atIndex:(NSUInteger)index
{
	MRPickerComponent *component = [[MRPickerComponent alloc] initWithPickerView:self withLoop:loop];
	[self insertComponent:component atIndex:index];
	
	return component;
}

/*===================================================================
 说明:
	插入组件
 ==================================================================*/
- (void)insertComponent:(MRPickerComponent *)component atIndex:(NSUInteger)index
{
	[_components insertObject:component atIndex:index];
	[self insertSubview:component atIndex:index];
	[self setNeedsLayout];
}

- (void)replaceComponentAtIndex:(NSUInteger)index withComponent:(MRPickerComponent *)component
{
	MRPickerComponent *c = _components[index];
	[_components replaceObjectAtIndex:index withObject:component];
	[c removeFromSuperview];
	
	[self setNeedsLayout];
}

/*===================================================================
 说明:
    返回组件
 ==================================================================*/
- (MRPickerComponent *)firstComponent
{
	return _components.firstObject;
}

- (MRPickerComponent *)componentAtIndex:(NSUInteger)index
{
	if (index < _components.count)
		return [_components objectAtIndex:index];
	
	return nil;
}

- (MRPickerComponent *)componentWithTag:(NSInteger)tag
{
	for (MRPickerComponent *c in _components)
	{
		if (c.tag == tag) return c;
	}
	
	return nil;
}

/*===================================================================
 说明:
    移除组件
 ==================================================================*/
- (void)removeAllComponents
{
	for (MRPickerComponent *component in _components)
	{
		[component removeFromSuperview];
	}
	
    [self.components removeAllObjects];
}

- (void)removeComponentAtIndex:(NSUInteger)index
{
	if (index < _components.count)
	{
		[self removeComponent:_components[index]];
	}
}

- (void)removeComponent:(MRPickerComponent *)component
{
	if ([_components containsObject:component])
	{
		[component removeFromSuperview];
		[_components removeObject:component];
		[self setNeedsLayout];
	}
}

#pragma mark - 日期组件
/*===================================================================
 说明:
	日期组件
 ==================================================================*/
- (void)addDateComponent
{
	[self addDateComponentWithMinYear:1900 maxYear:2099];
}

- (void)addDateComponentWithMinYear:(NSInteger)minYear maxYear:(NSInteger)maxYear
{
	__weak MRPickerComponent *year  = [self addComponent];
	__weak MRPickerComponent *month = [self addComponentWithLoop:YES];
	__weak MRPickerComponent *day   = [self addComponentWithLoop:YES];
	
	year.tag  = 20000;
	month.tag = 20001;
	day.tag   = 20002;
	
	[year setRangeWithMax:maxYear withMin:minYear];
	[month setItems:[NSDateFormatter new].shortMonthSymbols];
	//[month setRangeWithMax:12 withMin:1];
	[day setRangeWithMax:31 withMin:1];
	
	__weak id this = self;
	[year didSelect:^(MRPickerComponent *component) {
		if (month.index == 1) [this pickerMonthDay];
	}];
	
	[month didSelect:^(MRPickerComponent *component) {
		[this pickerMonthDay];
	}];
}

//检测月分天数
- (void)pickerMonthDay
{
	NSUInteger year  = [self componentWithTag:20000].value;
	NSUInteger month = [self componentWithTag:20001].index;
	
	//获取当前月天数
	int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	
	//闰月天数
	if (month == 1 && 0 == (year % 4) && (0 != (year % 100) || 0 == (year % 400))) days[1] = 29;
	
	[[self componentWithTag:20002] setRangeWithMax:days[month] withMin:1];
}

- (NSDate *)pickerDate
{
	uint year  = (uint)[self componentWithTag:20000].value;
	uint month = (uint)[self componentWithTag:20001].index + 1;
	uint day   = (uint)[self componentWithTag:20002].value;
	
	NSDateFormatter *df = [[NSDateFormatter alloc] init];
	df.dateFormat = @"yyyy-MM-dd";
	
	return [df dateFromString:[NSString stringWithFormat:@"%04d-%02d-%02d", year, month, day]];
}

- (void)setPickerDate:(NSDate *)pickerDate
{
	[self setPickerDate:pickerDate animated:YES];
}

- (void)setPickerDate:(NSDate *)pickerDate animated:(BOOL)animated
{
	NSDateComponents *date = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:pickerDate];
	
	[[self componentWithTag:20000] setIndex:date.year - 1900 animated:animated];
	[[self componentWithTag:20001] setIndex:date.month - 1 animated:animated];
	[[self componentWithTag:20002] setIndex:date.day - 1 animated:animated];
}

#pragma mark - 区域组件
/*===================================================================
 说明:
	区域组件
 ==================================================================*/
- (void)addRegionComponent
{
	__weak MRPickerComponent *country  = [self addComponent];
	__weak MRPickerComponent *province = [self addComponent];
	__weak MRPickerComponent *city     = [self addComponent];
	
	country.tag  = 10000;
	province.tag = 10001;
	city.tag     = 10002;
	
	[country didSelect:^(MRPickerComponent *c) {
		if (c.items.count) province.items = [FSRegion provincesForCountry:[c.items[c.index][@"id"] intValue]];
		city.items = nil;
		province.index = 0;
	}];
	
	[province didSelect:^(MRPickerComponent *c) {
		if (c.items.count) city.items = [FSRegion citiesForProvince:[c.items[c.index][@"id"] intValue]];
		city.index = 0;
	}];
	
	country.items = [FSRegion countries];
	country.index = 0;
}

- (NSUInteger)pickerCountry
{
	MRPickerComponent *c = [self componentWithTag:10000];
	return c.items.count ? [c.items[c.index][@"id"] intValue] : 0;
}

- (NSUInteger)pickerProvince
{
	MRPickerComponent *c = [self componentWithTag:10001];
	return c.items.count ? [c.items[c.index][@"id"] intValue] : 0;
}

- (NSUInteger)pickerCity
{
	MRPickerComponent *c = [self componentWithTag:10002];
	return c.items.count ? [c.items[c.index][@"id"] intValue] : 0;
}

- (NSString *)pickerRegion
{
	return [FSRegion regionWithCity:self.pickerCity];
}

- (void)setPickerCity:(NSUInteger)pickerCity
{
	[self setPickerCity:pickerCity animated:YES];
}

- (void)setPickerCity:(NSUInteger)pickerCity animated:(BOOL)animated
{
	if (pickerCity)
	{
		NSInteger	country, province, city;
		[FSRegion indexWithCity:pickerCity country:&country province:&province city:&city];
		
		[[self componentWithTag:10000] setIndex:country animated:animated];
		[[self componentWithTag:10001] setIndex:province animated:animated];
		[[self componentWithTag:10002] setIndex:city animated:animated];
	}
}

@end
